package ottoFebDuemilaundici;

import java.util.Iterator;

import positionList.BoundaryViolationException;
import positionList.InvalidPositionException;
import positionList.Position;
import binaryTree.EmptyTreeException;
import binaryTree.LinkedBinaryTree;

public class MyTree<E> implements Tree<E> {

	protected LinkedBinaryTree<E> t; // albero binario proprio

	public MyTree() { // costruttore

		t = new LinkedBinaryTree<E>();

		t.addRoot(null); // nodo esterno di t: non contiene dati
	}

	public int size() {
		return t.size();
	}

	public boolean isEmpty() {
		return t.isEmpty();
	}

	public boolean isInternal(Position<E> v) throws InvalidPositionException {
		if (t.hasLeft(v))
			return true;
		else return false;
	}

	public boolean isRoot(Position<E> v) throws InvalidPositionException {
		return t.isRoot(v);
	}

	public Position<E> root() throws EmptyTreeException {
		return t.root();
	}

	public Position<E> parent(Position<E> v) throws InvalidPositionException,
			BoundaryViolationException {
		Position<E> attuale = v;
		while(true) {
		Position<E> candidato = t.parent(attuale);
		Position<E> figlio = t.left(candidato);
		if (figlio==attuale) 
			return candidato;
		attuale=candidato;
		}
	}

	public Iterator<Position<E>> children(Position<E> v)
			throws InvalidPositionException {
		return new ChildrenIterator<E>(t, v);
	}// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

	// classe interna: ha accesso alla struttura dati interna di MyTree
	static class ChildrenIterator<E> implements Iterator<Position<E>> {
		private Position<E> cur; // posizione corrente
		private LinkedBinaryTree<E> T; //
		private Position<E> padre;

		// COSTRUTTORE
		public ChildrenIterator(LinkedBinaryTree<E> tree, Position<E> p) {
			padre=p;
			cur=p;
			T=tree;
		}

		public boolean hasNext() {
			if(cur==padre && T.hasLeft(cur)) {
				return true;
			}
			else if(T.hasRight(cur)) {
				return true;
			}
			else {
				return false;
			}
		}

		public Position<E> next() {
			if(cur==padre) {
				cur = T.left(cur);
				return cur;
			}
			else {
				cur = T.right(cur);
				return cur;
			}
			
		}
		public void remove() {
			// non richiesto
		}
	} // end class ChildrenIterator

}// end class MyTree

